package com.linkgie.galaxyframework.shell;

import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import com.linkgie.galaxyframework.utils.CollectionUtils;

public class InputOptions {

    private List<List<InputOption>> groups = new LinkedList<>();

    private Set<String> groupSet = new LinkedHashSet<>();

    private InputOptions() {
    }

    public List<InputOption> toList() {
        List<InputOption> allOptions = new LinkedList<>();
        for (List<InputOption> optionsGroup : this.groups) {
            allOptions.addAll(optionsGroup);
        }
        return allOptions;
    }

    public InputOption[] toArray() {
        List<InputOption> allOptions = new LinkedList<>();
        for (List<InputOption> optionsGroup : this.groups) {
            allOptions.addAll(optionsGroup);
        }
        return CollectionUtils.toArray(allOptions, InputOption.class);
    }

    public static GroupedOptionsBuilder option(String value) {
        InputOptions options = new InputOptions();
        return new GroupedOptionsBuilder(options).option(value);
    }

    public static GroupedOptionsBuilder option(String value, String description) {
        InputOptions options = new InputOptions();
        return new GroupedOptionsBuilder(options).option(value, description);
    }

    public static GroupedOptionsBuilder group(String group) {
        InputOptions options = new InputOptions();
        return new GroupedOptionsBuilder(group, options);
    }

    public static class GroupedOptionsBuilder {

        private InputOptions context;

        private String group;
        private List<InputOption> options = new LinkedList<>();

        private GroupedOptionsBuilder(InputOptions context) {
            // 默认分组为空；
            this.context = context;
        }

        private GroupedOptionsBuilder(String group, InputOptions context) {
            this(context);
            this.group = group;
        }

        public GroupedOptionsBuilder option(String value) {
            this.options.add(InputOption.ofValue(value).group(group).complete());
            return this;
        }

        public GroupedOptionsBuilder option(String value, String description) {
            this.options.add(InputOption.ofValue(value).description(description).group(group).complete());
            return this;
        }

        public GroupedOptionsBuilder option(String value, String display, String description) {
            this.options.add(InputOption.ofValue(value).display(display).description(description).group(group).complete());
            return this;
        }

        /**
         * 创建分组；
         * 
         * @param newGroup 分组；允许为 null ；
         * @return
         */
        public GroupedOptionsBuilder nextGroup(String newGroup) {
            flushGroupOptions();

            if (context.groupSet.contains(newGroup)) {
                throw new IllegalStateException("Group '" + newGroup + "' already exist!");
            }
            
            GroupedOptionsBuilder builder = new GroupedOptionsBuilder(newGroup, context);
            return builder;
        }

        private void flushGroupOptions() {
            if (this.group != null && context.groupSet.contains(this.group)) {
                throw new IllegalStateException("Group '" + this.group + "' already exist!");
            }
            context.groups.add(this.options);
        }

        public InputOptions complete() {
            flushGroupOptions();
            
            return context;
        }

    }

}
